package ongd.servicios.persistencia;

import java.io.Serializable;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import ongd.negocio.gestion.Cuota;
import ongd.negocio.gestion.CuotaPK;
import ongd.negocio.gestion.Entidad;
import ongd.negocio.gestion.Persona;
import ongd.servicios.persistencia.exceptions.NonexistentEntityException;
import ongd.servicios.persistencia.exceptions.PreexistingEntityException;

/**
 * Clase que contiene los método que para realizar operaciones
 * sobre la base de datos referente a la entidad cuota.
 *
 * @author <a href="mailto:egi0002@alu.ubu.es">Elena García Iglesias</a>
 * @author <a href="mailto:cms0021@alu.ubu.es">Cristina Martínez Sanz</a>
 * @version 1.0 20120124
 *
 */
public class CuotaJpaController extends AJPAControlador implements Serializable {

    /**
     * Objeto de tipo EntityManager.
     */
    private EntityManager em = null;

    /**
     * Constructor de la clase.
     * @param em EntityManager
     */
    public CuotaJpaController(EntityManager em) {
        this.em = em;
    }

    /**
     * Método que crea un objeto de tipo cuota en la base de datos.
     * @param entidad Objeto que crearemos 
     * @param et Booleano que indica si hay que iniciar la transacción
     * @throws PreexistingEntityException
     * @throws Exception 
     */
    @Override
    public void create(Entidad entidad, boolean et) throws PreexistingEntityException, Exception {
        Cuota cuota = (Cuota) entidad;
        if (cuota.getCuotaPK() == null) {
            cuota.setCuotaPK(new CuotaPK());
        }
        cuota.getCuotaPK().setPersonaDNI(cuota.getPersona().getDni());
        try {
            //Si et es falso significa que tengo que crear la transacción
            if (!et) {
                em.getTransaction().begin();
            }
            Persona persona = cuota.getPersona();
            if (persona != null) {
                persona = em.getReference(persona.getClass(), persona.getDni());
                cuota.setPersona(persona);
            }
            em.persist(cuota);
            if (persona != null) {
                persona.getCuotaList().add(cuota);
                persona = em.merge(persona);
            }
            //Si et es falso significa que tengo que terminar la transaccion
            if (!et) {
                em.getTransaction().commit();
            }
        } catch (Exception ex) {
            if (findEntidad(Cuota.class, cuota.getCuotaPK()) != null) {
                throw new PreexistingEntityException("Cuota " + cuota + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
//                em.close();
            }
        }
    }

    /**
     * Método que edita un objeto de tipo cuota en la base de datos.
     * @param entidad Entidad que editaremos
     * @param et Booleano que indica si hay que iniciar la transacción
     * @throws NonexistentEntityException
     * @throws Exception 
     */
    @Override
    public void edit(Entidad entidad, boolean et) throws NonexistentEntityException, Exception {
        Cuota cuota = (Cuota) entidad;
        cuota.getCuotaPK().setPersonaDNI(cuota.getPersona().getDni());
        try {
            //Si et es falso significa que tengo que crear la transacción
            if (!et) {
                em.getTransaction().begin();
            }
            Cuota persistentCuota = em.find(Cuota.class, cuota.getCuotaPK());
            Persona personaOld = persistentCuota.getPersona();
            Persona personaNew = cuota.getPersona();
            if (personaNew != null) {
                personaNew = em.getReference(personaNew.getClass(), personaNew.getDni());
                cuota.setPersona(personaNew);
            }
            cuota = em.merge(cuota);
            if (personaOld != null && !personaOld.equals(personaNew)) {
                personaOld.getCuotaList().remove(cuota);
                personaOld = em.merge(personaOld);
            }
            if (personaNew != null && !personaNew.equals(personaOld)) {
                personaNew.getCuotaList().add(cuota);
                personaNew = em.merge(personaNew);
            }
            //Si et es falso significa que tengo que terminar la transaccion
            if (!et) {
                em.getTransaction().commit();
            }
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                CuotaPK id = cuota.getCuotaPK();
                if (findEntidad(Cuota.class, id) == null) {
                    throw new NonexistentEntityException("The cuota with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
//                em.close();
            }
        }
    }

    /**
     * Método que borra un objeto de tipo cuota de la base de datos.
     * @param clase Clase correpondiente al objeto a borrar
     * @param id Clave primaria del objeto a borrar
     * @param et Booleano que indica si hay que iniciar la transaccion
     * @throws NonexistentEntityException 
     */
    @Override
    public void destroy(Class clase, Object id, boolean et) throws NonexistentEntityException {
        try {
            //Si et es falso significa que tengo que crear la transacción
            if (!et) {
                em.getTransaction().begin();
            }
            Cuota cuota;
            try {
                cuota = (Cuota) em.getReference(clase, id);
                cuota.getCuotaPK();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The cuota with id " + id + " no longer exists.", enfe);
            }
            Persona persona = cuota.getPersona();
            if (persona != null) {
                persona.getCuotaList().remove(cuota);
                persona = em.merge(persona);
            }
            em.remove(cuota);
            //Si et es falso significa que tengo que terminar la transaccion
            if (!et) {
                em.getTransaction().commit();
            }
        } finally {
            if (em != null) {
//                em.close();
            }
        }
    }

    /**
     * Método que busca una cuota en la base de datos.
     * @param clase Class correspondiente al objeto a buscar
     * @param id Clave primaria del objeto a buscar
     * @return cuota
     */
    @Override
    public Cuota findEntidad(Class clase, Object id) {
        try {
            return (Cuota) em.find(clase, id);
        } finally {
//            em.close();
        }
    }
}
